package com.ruoyi.common.utils;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

import org.springframework.util.StringUtils;

public final class newDateUtil {
    public static final SimpleDateFormat FORMAT_YYYY_MM;

    public static final SimpleDateFormat FORMAT_YYYY_MM_DD;

    public static final SimpleDateFormat FORMAT_YMDHMS = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static final Pattern PATTERN_YYYY_MM;

    public static final Pattern PATTERN_YYYY_MM_DD;

    public static final Pattern PATTERN_YYYY_MM_DD_HH_MM_SS;

    static {
        FORMAT_YYYY_MM_DD = new SimpleDateFormat("yyyy-MM-dd");
        FORMAT_YYYY_MM = new SimpleDateFormat("yyyy-MM");
        PATTERN_YYYY_MM_DD_HH_MM_SS = Pattern.compile("[0-9]{4}-[0-9]{1,2}-[0-9]{1,2} [0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}");
        PATTERN_YYYY_MM_DD = Pattern.compile("[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}");
        PATTERN_YYYY_MM = Pattern.compile("[0-9]{4}-[0-9]{1,2}");
    }

    public static long currentTimeSeconds() {
        return System.currentTimeMillis() / 1000L;
    }

    public static String getFullString() {
        return (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date());
    }

    public static String getYMDString() {
        return (new SimpleDateFormat("yyyyMMdd")).format(new Date());
    }

    public static String getYMString() {
        return (new SimpleDateFormat("yyyyMM")).format(new Date());
    }

    public static String getTimeString(long millis) {
        return FORMAT_YMDHMS.format(new Date(millis));
    }

    public static Date toDate(String strDate) {
        strDate = strDate.replaceAll("/", "-");
        try {
            if (PATTERN_YYYY_MM_DD_HH_MM_SS.matcher(strDate).find())
                return FORMAT_YMDHMS.parse(strDate);
            if (PATTERN_YYYY_MM_DD.matcher(strDate).find())
                return FORMAT_YYYY_MM_DD.parse(strDate);
            if (PATTERN_YYYY_MM.matcher(strDate).find())
                return FORMAT_YYYY_MM.parse(strDate);
            throw new RuntimeException("未知的日期格式化字符串");
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    public static long toTimestamp(String strDate) {
        return toDate(strDate).getTime();
    }

    public static long toSeconds(String strDate) {
        return toTimestamp(strDate) / 1000L;
    }

    public static long toMillSeconds(String strDate) {
        return toTimestamp(strDate);
    }


    public static String timestampToDateStr(long time) {
        Timestamp timestamp = new Timestamp(time * 1000L);
        Date date = new Date();
        date = timestamp;
        String dateStr = getDateStr(date, "yyyy-MM-dd");
        return dateStr;
    }


    public static boolean compareDayTime(Calendar d1, Calendar d2) {
        int d1_year = d1.get(1);
        int d1_month = d1.get(2);
        int d1_day = d1.get(5);
        int d2_year = d2.get(1);
        int d2_month = d2.get(2);
        int d2_day = d2.get(5);
        if (d1_year == d2_year && d1_month == d2_month && d1_day == d2_day)
            return true;
        return false;
    }

    public static boolean compareMonthTime(Calendar d1, Calendar d2) {
        int d1_year = d1.get(1);
        int d1_month = d1.get(2);
        int d2_year = d2.get(1);
        int d2_month = d2.get(2);
        if (d1_year == d2_year && d1_month == d2_month)
            return true;
        return false;
    }

    public static Date getNextDay(Date currentDay) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(currentDay);
        calendar.add(5, 1);
        Date nextDay = calendar.getTime();
        return nextDay;
    }

    public static Date getTodayMorning() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        cal.set(11, 0);
        cal.set(13, 0);
        cal.set(12, 0);
        cal.set(14, 0);
        return cal.getTime();
    }

    public static Date getTodayNight() {
        Calendar cal = Calendar.getInstance();
        cal.set(11, 24);
        cal.set(13, 0);
        cal.set(12, 0);
        cal.set(14, 0);
        return cal.getTime();
    }

    public static long getOnedayNextDay(long times, int days, int type) {
        long ruleTimes = 86400L;
        return (0 == type) ? (times + 86400L * days) : (times - 86400L * days);
    }

    public static Date getYesterdayMorning() {
        Calendar cal = Calendar.getInstance();
        cal.add(5, -1);
        cal.set(11, 0);
        cal.set(13, 0);
        cal.set(12, 0);
        cal.set(14, 0);
        return cal.getTime();
    }

    public static Date getYesterdayLastTime() {
        Calendar cal = Calendar.getInstance();
        cal.add(5, -1);
        cal.set(11, 23);
        cal.set(13, 0);
        cal.set(12, 59);
        cal.set(14, 0);
        return cal.getTime();
    }

    public static Date getYesterdayNight() {
        Calendar cal = Calendar.getInstance();
        cal.add(5, -1);
        cal.set(11, 24);
        cal.set(13, 0);
        cal.set(12, 0);
        cal.set(14, 0);
        return cal.getTime();
    }

    public static Date getTomorrowMorning() {
        Calendar cal = Calendar.getInstance();
        cal.add(5, 1);
        cal.set(11, 0);
        cal.set(13, 0);
        cal.set(12, 0);
        cal.set(14, 0);
        return cal.getTime();
    }

    public static Date getTomorrowLastTime() {
        Calendar cal = Calendar.getInstance();
        cal.add(5, 1);
        cal.set(11, 23);
        cal.set(13, 0);
        cal.set(12, 59);
        cal.set(14, 0);
        return cal.getTime();
    }

    public static Date getTomorrowNight() {
        Calendar cal = Calendar.getInstance();
        cal.add(5, 1);
        cal.set(11, 24);
        cal.set(13, 0);
        cal.set(12, 0);
        cal.set(14, 0);
        return cal.getTime();
    }

    public static Date getWeekMorning() {
        Calendar cal = Calendar.getInstance();
        cal.set(cal.get(1), cal.get(2), cal.get(5), 0, 0, 0);
        cal.set(7, 2);
        return cal.getTime();
    }

    public static Date getWeekNight() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getWeekMorning());
        cal.add(7, 7);
        return cal.getTime();
    }

    public static Date getMonthMorning() {
        Calendar cal = Calendar.getInstance();
        cal.set(cal.get(1), cal.get(2), cal.get(5), 0, 0, 0);
        cal.set(5, cal.getActualMinimum(5));
        return cal.getTime();
    }

    public static Date getMonthNight() {
        Calendar cal = Calendar.getInstance();
        cal.set(cal.get(1), cal.get(2), cal.get(5), 0, 0, 0);
        cal.set(5, cal.getActualMaximum(5));
        cal.set(11, 24);
        return cal.getTime();
    }

    public static Date getLastMonthMorning() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        cal.add(2, -1);
        cal.set(5, 1);
        cal.set(11, 0);
        cal.set(13, 0);
        cal.set(12, 0);
        cal.set(14, 0);
        return cal.getTime();
    }

    public static Date getPreviousWeekday() {
        Calendar cal = Calendar.getInstance();
        cal.setFirstDayOfWeek(2);
        cal.add(5, -7);
        cal.set(7, 2);
        cal.set(11, 0);
        cal.set(13, 0);
        cal.set(12, 0);
        cal.set(14, 0);
        return cal.getTime();
    }

    public static Date getLastYear() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        cal.add(1, -1);
        cal.set(11, 0);
        cal.set(13, 0);
        cal.set(12, 0);
        cal.set(14, 0);
        return cal.getTime();
    }

    public static Date getLastMonth() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        cal.add(2, -1);
        cal.set(11, 0);
        cal.set(13, 0);
        cal.set(12, 0);
        cal.set(14, 0);
        return cal.getTime();
    }

    public static Date getLast3Month() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        cal.add(2, -3);
        return cal.getTime();
    }

    public static Date getPreviousWeekSunday() {
        Calendar cal = Calendar.getInstance();
        cal.setFirstDayOfWeek(2);
        cal.add(5, -7);
        cal.set(7, 1);
        cal.set(11, 23);
        cal.set(13, 0);
        cal.set(12, 59);
        cal.set(14, 0);
        return cal.getTime();
    }

    public static String strToDateTime(long strDateTime) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = new Date(strDateTime * 1000L);
        String timestamp = simpleDateFormat.format(date);
        return timestamp;
    }

    public static String TimeToStr(Date date) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        return format.format(date);
    }

    public static Date strYYMMDDToDate(String strYYMMDD) {
        SimpleDateFormat format = new SimpleDateFormat("yy-MM-dd");
        try {
            return format.parse(strYYMMDD);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static Date getDate(String time, String pattern) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        if (!StringUtils.isEmpty(time))
            return sdf.parse(time);
        return null;
    }

    public static String getDateStr(Date date, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.format(date);
    }

    public static Integer calculateCurrentTime2SecondDaySec() {
        Long currentTime = Long.valueOf(System.currentTimeMillis());
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(currentTime.longValue());
        calendar.set(11, 0);
        calendar.set(12, 0);
        calendar.set(13, 0);
        calendar.set(14, 0);
        calendar.add(5, 1);
        Long endTime = Long.valueOf(calendar.getTimeInMillis());
        return Integer.valueOf((int) (endTime.longValue() - currentTime.longValue()) / 1000);
    }

    public static boolean authRequestTime(long time) {
        long currTime = currentTimeSeconds();
        long l = currTime - time;
        if (currTime - time < 60L && currTime - time > -60L)
            return true;
        System.out.println(String.format("====> authRequestTime error server > %s client %s", new Object[]{Long.valueOf(currTime), Long.valueOf(time)}));
        return false;
    }

    public static Map<String, Integer> getYearMonthWeek() {
        Map<String, Integer> data = new HashMap<>();
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(2);
        int year = calendar.get(1);
        int month = calendar.get(2) + 1;
        int week = calendar.get(3);
        data.put("year", Integer.valueOf(year));
        data.put("month", Integer.valueOf(month));
        data.put("week", Integer.valueOf(week));
        return data;
    }

    public static LocalDateTime plusDay(LocalDate start, Integer day) {
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDate localDate = start.plusDays(day.intValue());
        String format = localDate.format(dateFormatter);
        format = format + " 23:59:59";
        LocalDateTime time = LocalDateTime.parse(format, dateTimeFormatter);
        return time;
    }

    public static LocalDateTime plusDay(Integer day) {
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDate now = LocalDate.now();
        LocalDate localDate = now.plusDays(day.intValue());
        String format = localDate.format(dateFormatter);
        format = format + " 23:59:59";
        LocalDateTime time = LocalDateTime.parse(format, dateTimeFormatter);
        return time;
    }

    public static LocalDateTime plusMonth(LocalDate start, Integer month) {
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDate localDate = start.plusMonths(month.intValue()).minusDays(1L);
        String format = localDate.format(dateFormatter);
        format = format + " 23:59:59";
        LocalDateTime time = LocalDateTime.parse(format, dateTimeFormatter);
        return time;
    }

    public static LocalDateTime plusMonth(Integer month) {
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDate now = LocalDate.now();
        LocalDate localDate = now.plusMonths(month.intValue()).minusDays(1L);
        String format = localDate.format(dateFormatter);
        format = format + " 23:59:59";
        LocalDateTime time = LocalDateTime.parse(format, dateTimeFormatter);
        return time;
    }

    public static LocalDateTime plusYear(LocalDate start, Integer year) {
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDate localDate = start.plusYears(year.intValue()).minusDays(1L);
        String format = localDate.format(dateFormatter);
        format = format + " 23:59:59";
        LocalDateTime time = LocalDateTime.parse(format, dateTimeFormatter);
        return time;
    }

    public static LocalDateTime plusYear(Integer year) {
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDate now = LocalDate.now();
        LocalDate localDate = now.plusYears(year.intValue()).minusDays(1L);
        String format = localDate.format(dateFormatter);
        format = format + " 23:59:59";
        LocalDateTime time = LocalDateTime.parse(format, dateTimeFormatter);
        return time;
    }

    public static String addYear(Date date, Integer num) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(1, num.intValue());
        Date nextDay = calendar.getTime();
        return getDateStr(nextDay, "yyyy-MM-dd");
    }

    public static String subYear(Date date, Integer num) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(1, -num.intValue());
        Date nextDay = calendar.getTime();
        return getDateStr(nextDay, "yyyy-MM-dd");
    }

    public static String subYearNew(Date date, Integer num) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(1, -num.intValue());
        Date nextDay = calendar.getTime();
        return getDateStr(nextDay, "yyyy");
    }

    public static String dateDifferenceDesc(long now, long early) {
        String res = "";
        Long preTime = Long.valueOf(now - early);
        if (preTime.longValue() < 60000L) {
            res = "刚刚";
        } else if (preTime.longValue() < 3600000L) {
            res = (preTime.longValue() / 60000L) + "分钟前";
        } else if (preTime.longValue() < 86400000L) {
            res = (preTime.longValue() / 3600000L) + "小时前";
        } else if (preTime.longValue() < 172800000L) {
            res = "昨天";
        } else if (preTime.longValue() < 259200000L) {
            res = "前天";
        } else if (preTime.longValue() < 31536000000L) {
            res = (preTime.longValue() / 86400000L) + "天前";
        } else {
            res = (preTime.longValue() / 31536000000L) + "年前";
        }
        return res;
    }

    public static String getDateStr(String dateStr) {
        String str = null;
        String s = dateStr.substring(2, 3);
        int s1 = Integer.valueOf(dateStr.substring(3, 4)).intValue();
        if (s1 >= 5) {
            str = s + "5后";
        } else {
            str = s + "0后";
        }
        return str;
    }
}
